package com.wtgroup.demo.mianshi.其他;

/**
 * @author dafei
 * @version 0.1
 * @date 2020/6/24 10:07
 */
public class Q1 {
    /* 
    1. 找方法时, 在声明类里找, 并结合向上转型. => 方法id
    2. 执行时, 实际类型实例里, 执行对应 方法id 的方法.
    
    向上转型, 先向上转一级, 不行, 再向上.
    */
    public static void main(String[] args) {
        A a1 = new A();
        A a2 = new B();
        B b = new B();
        C c = new C();
        D d = new D();

        System.out.println("1--" + a1.show(b));
        System.out.println("2--" + a1.show(c));
        System.out.println("3--" + a1.show(d));
        // 初始签名: A.show(B)
        // 1. 在 A 的方法表中找. 没有找到.
        // 2. 将入参 B 向上转型一级变成了 A . 签名: A.show(A). 再找, 找到了, 获取方法偏移量.
        // 3. 执行方法, 执行时, 实际类型是 B , 依据上面的偏移量查看有无重写该方法, 有直接调用, 没有在父类的方发表里找.
        // 这里 B 里找到了重写的, 直接调用执行.
        // 方法偏移量, 大大提高检索效率. 子类继承父类的方法的偏移量和父类中是一样的.
        System.out.println("4--" + a2.show(b)); // A.show(B), 没有, B 向上转型再找 -> show(A) -> 执行时, 实例类型实例里的 show(A) => 4--B and A
        System.out.println("5--" + a2.show(c)); // A.show(C) => 5--B and A
        System.out.println("6--" + a2.show(d)); // A.show(D) => 6--A and D
        System.out.println("7--" + b.show(b));  // 7--B and B
        System.out.println("8--" + b.show(c)); // ?? B.show(C) => 8--B and B
        System.out.println("9--" + b.show(d)); // 9--A and D
    }

}
class A {
    public String show(D obj) {
        return ("A and D");
    }

    public String show(A obj) {
        return ("A and A");
    }

}

class B extends A{
    public String show(B obj){
        return ("B and B");
    }

    public String show(A obj){
        return ("B and A");
    }
    // 继承
    // public String show(D obj)
}

class C extends B{

}

class D extends B{

}

